//
// SoapTrace.Net - A soap message monitoring utility.
//
// Copyright (C) 2004 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using SoapTrace.Core.Communication;
using SoapTrace.Core.Formatters;
using SoapTrace.Tests.Utils;
using System;
using System.IO;
using NUnit.Framework;

namespace SoapTrace.Tests
{
	/// <summary>
	/// Tests formatting of soap requests containing arrays using the 
	/// <see cref="SoapMessageFormatter"/>.</summary>
	[ TestFixture ]
	public class ParameterArraySoapFormatterTestFixture
	{
		/// <summary>
		/// The soap message formatter's configuration.
		/// </summary>
		private SoapMessageFormatterConfig m_Config = 
			new SoapMessageFormatterConfig( );
		
		/// <summary>
		/// The soap message formatter under test.
		/// </summary>
		private SoapMessageFormatter m_Formatter;

		/// <summary>
		/// The name of the web service that will be passed to the formatter.
		/// </summary>
		private string m_WebServiceName = "Test";

		/// <summary>
		/// The uri of the web service that will be passed to the formatter.
		/// </summary>
		private string m_Uri = "Test.asmx";

		/// <summary>
		/// The web service operation's name passed to the formatter.
		/// </summary>
		private string m_WebServiceMethod = "getTest";

		/// <summary>
		/// The mock soap message that contains the message to be formatted.
		/// </summary>
		private MockSoapMessage m_MockMessage;

		/// <summary>
		/// The soap request message to be formatted.
		/// </summary>
		private string m_SoapRequestMessage = String.Empty;

		/// <summary>
		/// The expected formatted request.
		/// </summary>
		private string m_ExpectedFormattedRequestXml = String.Empty;
		
		/// <summary>
		/// Initialises each test.
		/// </summary>
		[ SetUp ]
		public void Init( )
		{
			StringReader Reader = new StringReader( GetConfigXml( ) );
			m_Config = SoapMessageFormatterConfig.Load( Reader );

			m_Formatter = new SoapMessageFormatter( m_Config.WebServices );

			m_MockMessage = new MockSoapMessage( );

			SetSoapRequestMessage( );
		}
	
		/// <summary>
		/// Tests whether the request xml is correctly formatted. 
		/// </summary>
		[ Test ]
		public void RequestXmlFormatting( )
		{
			// Set expected formatting xml.
			
			m_ExpectedFormattedRequestXml = "getTest\r\n\r\n" +
				"string: \r\n" +
				"<test>\r\n" +
				"\t<item />\r\n" +
				"\t<item />\r\n" +
				"</test>\r\n\r\n" +
				"string: \r\n" +
				"<item>\r\n" +
				"\t<data>value1</data>\r\n" +
				"</item>\r\n\r\n" +
				"string: \r\n" +
				"<item>\r\n" +
				"\t<data>value2</data>\r\n" +
				"</item>\r\n\r\n";
			
			CheckFormatting( );
		}
		
		/// <summary>
		/// Tests that we can hide an array item for a parameter
		/// by setting the <see cref="WebServiceArrayItem.Display"/> flag to false.
		/// </summary>
		[ Test ]
		public void FirstParameterNotDisplayed( )
		{
			// Hide first parameter.
			m_Config.WebServices[ 0 ].Operations[ 0 ].Parameters[ 0 ].Items[ 0 ].Display = false;
						
			// Set expected formatting xml.
			
			m_ExpectedFormattedRequestXml = "getTest\r\n\r\n" +
				"string: \r\n" +
				"<item>\r\n" +
				"\t<data>value1</data>\r\n" +
				"</item>\r\n\r\n" +
				"string: \r\n" +
				"<item>\r\n" +
				"\t<data>value2</data>\r\n" +
				"</item>\r\n\r\n";			

			CheckFormatting( );
		}
		
		/// <summary>
		/// Tests that the parameter type information is used if an
		/// individual array item's information is not specified.
		/// </summary>
		[ Test ]
		public void NoArrayItemSettings( )
		{
			m_Config.WebServices[ 0 ].Operations[ 0 ].Parameters[ 0 ].Items.Clear( );
			RequestXmlFormatting( );
		}
		
		
		/// <summary>
		/// Tests that the formatting is correct.
		/// </summary>
		private void CheckFormatting( )
		{
			m_MockMessage.SetMessage( m_SoapRequestMessage );

			IMessageFormatter Formatter = ( IMessageFormatter )m_Formatter;

			FormattedText FormattedText = Formatter.FormatRequest( String.Empty,
				m_Uri,
				m_WebServiceName,
				m_WebServiceMethod,
				m_MockMessage );
			string FormattedRequest = FormattedText.Text;

			Assert.AreEqual( m_ExpectedFormattedRequestXml, FormattedRequest );			
		}
		
		/// <summary>
		/// Sets the soap message request.
		/// </summary>
		private void SetSoapRequestMessage( )
		{
			m_SoapRequestMessage = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n" +
				"	<soap:Body>\r\n" +
				"		<getTest xmlns=\"http://soaptrace.net/webservices\">\r\n" +
				"			<values>\r\n" +
				"				<string>&lt;test&gt;&lt;item/&gt;&lt;item/&gt;&lt;/test&gt;</string>\r\n" +
				"				<string>&lt;item&gt;&lt;data&gt;value1&lt;/data&gt;&lt;/item&gt;</string>\r\n" +
				"				<string>&lt;item&gt;&lt;data&gt;value2&lt;/data&gt;&lt;/item&gt;</string>\r\n" +
				"			</values>\r\n" +
				"		</getTest>\r\n" +
				"	</soap:Body>\r\n" +
				"</soap:Envelope>";
		}

		/// <summary>
		/// Gets the config xml to be used in this test fixture.  
		/// </summary>
		/// <remarks><para>The web service  represented by the xml has the 
		/// form:</para>
		/// <para>
		/// <code>void Test(string[] param1, string[] param2, string param3)</code>
		/// </para>
		/// </remarks>
		private string GetConfigXml( )
		{
			return "<soapmessageformatter.config xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
				"<webservice name='Test' uri='Test.asmx'>" +
				"	<operation name='getTest'>" +
				"		<params>" +
				"			<param type='xml.array' name='param1' display='true'>" +
				"				<item type='xml' name='item1' display='true'/>" +
				"				<item type='xml' name='item2' display='true'/>" +
				"				<item type='xml' name='item3' display='true'/>" +
				"			</param>" +
				"		</params>" +
				"	</operation>" +
				"</webservice>" +
				"</soapmessageformatter.config>";
		}
	}
}
